
#include"include/muduo/net/TcpServer.h"
#include"include/muduo/net/EventLoop.h"
#include"include/muduo/net/TcpConnection.h"
#include<iostream>
#include<functional>
#include<unordered_map>

class TranslateServer
{
public:
    TranslateServer(uint16_t port)
        :_server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port), 
        "TranslateServer", muduo::net::TcpServer::kReusePort)
    {
        //std::bind是一个函数适配器函数 对指定的函数进行参数绑定
        //setConnectionCallback，的函数参数 只能有一个参数 所以bind
        //setMessageCallback 同理
        auto func1 = std::bind(&TranslateServer::onConnection, this, std::placeholders::_1);
        auto func2 = std::bind(&TranslateServer::onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
        _server.setConnectionCallback(func1);
        _server.setMessageCallback(func2);
    }
    //启动服务器
    void start()
    {
        _server.start();    //开始监听
        _baseloop.loop();   //开始事件监控， 这是一个死循环接口
    }
private:
    //typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;
    //onConnetion 一个链接建立成功和链接关闭的时候被调用
    void onConnection(const muduo::net::TcpConnectionPtr& conn)
    {
        //新连接建立成功时的回调函数
        if(conn->connected() == true)
        {
            std::cout << "新连接建立成功" << std::endl;
        }
        else
        {
            std::cout << "新连接关闭" << std::endl;
        }
    }

    std::string translate(std::string &str)
    {
        static std::unordered_map<std::string, std::string> dict_map = 
        {
            {"hello", "您好"},
            {"hello", "您好"},
            {"你好", "hello"},
            {"您好", "Hello"}
        };
        auto it = dict_map.find(str);    
        if(it == dict_map.end())
        {
            return "没听懂";
        }
        else
        {
            return it->second;
        }

    }
    //typedef std::function<void (const TcpConnectionPtr&, Buffer*, Timestamp)> MessageCallback;
    void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp)
    {
        //通信链接收到请求时的回调函数
        //1.从buf中把请求数据取出来
        std::string str = buf->retrieveAllAsString();
        //2.进行业务处理translate
        std::string resp = translate(str);
        //3.对客户端进行响应
        conn->send(resp);
    }

private:
    //_baseloop 是epoll的事件监控， 会告诉描述符的事件监控， 触发事件后进行io操作
    muduo::net::EventLoop _baseloop;
    //server对象 主要用于设置回调函数 用于告诉服务器收到什么请求该如何处理
    muduo::net::TcpServer _server;
};

int main()
{
    TranslateServer server(8888);
    server.start();
    return 0;
}